#include <gflags/gflags.h>

#include <memory>
#include <string>
#include <thread>

#include "asr_server.h"
#include "channel.h"
#include "log.h"

DEFINE_int32(level, 1, "日志等级");
DEFINE_bool(mode, false, "调试模式-false, 发布模式-true");
DEFINE_string(path, "./logfile", "发布模式下日志输出到的文件路径");

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "etcd服务器地址");
DEFINE_string(asr_service, "/service/asr", "rpc请求目录");

void put_cb(std::string service_name, std::string service_host) {
    LOG_DEBUG("上线服务: {}-{}", service_name, service_host);
}

void del_cb(std::string service_name, std::string service_host) {
    LOG_DEBUG("下线服务: {}-{}", service_name, service_host);
}

int main(int argc, char* argv[]) {
    gflags::ParseCommandLineFlags(&argc, &argv, true);
    chat::initLogger(FLAGS_level, FLAGS_mode, FLAGS_path);

    // 1. 构造 RPC 服务管理对象
    chat::ServiceManagerPtr service_manager =
        std::make_shared<chat::ServiceManager>();
    service_manager->declared(FLAGS_asr_service);  // 添加关心

    // 2. 构造服务发现对象
    auto discovery = std::make_shared<chat::Discovery>(
        FLAGS_etcd_host, FLAGS_asr_service,
        std::bind(&chat::ServiceManager::onServiceOnline, service_manager.get(),
                  std::placeholders::_1, std::placeholders::_2),
        std::bind(&chat::ServiceManager::onServiceOffline,
                  service_manager.get(), std::placeholders::_1,
                  std::placeholders::_2));

    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(2));

        // 3. 通过 RPC 信道管理对象，获取提供 Echo 服务的信道
        chat::ServiceChannel::ChannelPtr channel =
            service_manager->choose(FLAGS_asr_service);
        if (channel == nullptr) {
            LOG_ERROR("没有能够提供 {} 的主机", FLAGS_asr_service);
            continue;
        }

        // 4. 发起 RPC 调用
        chat::SpeechService_Stub stub(channel.get());

        chat::SpeechRecognitionReq req;
        chat::SpeechRecognitionRsp* resp = new chat::SpeechRecognitionRsp;

        std::string file_content;
        if (aip::get_file_content("16k.pcm", &file_content)) {
            LOG_ERROR("获取pcm数据失败");
            return -1;
        }
        req.set_speech_content(file_content);

        brpc::Controller* controller = new brpc::Controller;

        stub.SpeechRecognition(controller, &req, resp, nullptr);  // 同步调用
        if (controller->Failed()) {
            LOG_ERROR("rpc调用失败, {}", controller->ErrorText());
            delete controller;
            delete resp;

            continue;
        }

        LOG_DEBUG("收到响应: {}", resp->recognition_result());

        delete controller;
        delete resp;

        break;
    }

    return 0;
}